package ar.republicagroup.gestion.services.impl;

import ar.republicagroup.gestion.dao.CajaDAO;
import ar.republicagroup.gestion.entities.Caja;
import ar.republicagroup.gestion.entities.CierreCaja;
import ar.republicagroup.gestion.entities.Cliente;
import ar.republicagroup.gestion.entities.ClienteSaldo;
import ar.republicagroup.gestion.entities.Liquidacion;
import ar.republicagroup.gestion.services.CajaServices;
import ar.republicagroup.gestion.services.ClienteSaldoServices;
import ar.republicagroup.gestion.services.ClienteServices;
import ar.republicagroup.gestion.services.LiquidacionServices;
import ar.republicagroup.gestion.services.MovimientoTipoServices;
import ar.republicagroup.gestion.util.SpringUtils;
import ar.republicagroup.gestion.util.helpers.FilterCaja;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import static ch.lambdaj.Lambda.*;

/**
 *
 * @author DIEGOALV
 */
public class CajaServicesImpl implements CajaServices {

    private CajaDAO cajaDao;
    
    private double efectivoCajaAnterior;
    private double efectivoCajaDelDia;
    private double totalRetiros;
    private double totalPagos;
    private double totalGastosDiarios;
    private double totalGastosBancos;
    
    

    public void setCajaDao(CajaDAO cajaDao) {
        this.cajaDao = cajaDao;
    }
    

    @Override
    public String insert(Caja beanCaja) {
        return cajaDao.insert(beanCaja);
    }

    @Override
    public String update(Caja beanCaja) {
        return cajaDao.update(beanCaja);
    }

    @Override
    public Caja get(Integer idcaja) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String delete(Integer idcaja) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Caja> getMovimientosCajaByFecha(Calendar fechaCaja) {
        return cajaDao.getMovimientosCajaByFecha(fechaCaja);
    }

    /* Bussiness Logic */
    
    @Override
    public void setEfectivoCajaAnterior(double efectivo) {
        this.efectivoCajaAnterior = efectivo;
    }

    @Override
    public void setEfectivoCajaDelDia(double efectivo) {
        this.efectivoCajaDelDia = efectivo;
    }

    @Override
    public void setTotalRetiros(double total) {
        this.totalRetiros = total;
    }

    @Override
    public void setTotalPagos(double total) {
        this.totalPagos = total;
    }

    @Override
    public void setTotalGastosDiarios(double total) {
        this.totalGastosDiarios = total;
    }

    @Override
    public void setTotalGastosBancos(double total) {
        this.totalGastosBancos = total;
    }

    @Override
    public double getTotalEfectivoEnCajaDelDia() {
       this.efectivoCajaDelDia = (efectivoCajaAnterior + totalRetiros) - (totalPagos + totalGastosDiarios); 
       return efectivoCajaDelDia;    
    }

    @Override
    public double getTotalEfectivoCajaAnterior() {
        return efectivoCajaAnterior;
    }

    @Override
    public void registrarMovimientosWithCierreCaja(List<Caja> movimientosList,CierreCaja cierre) {
        
        ClienteServices clienteServices             = (ClienteServices)SpringUtils.getBean("clienteServices");
        LiquidacionServices liquidacionServices     = (LiquidacionServices)SpringUtils.getBean("liquidacionServices");
        ClienteSaldoServices clienteSaldoServices   = (ClienteSaldoServices)SpringUtils.getBean("clienteSaldoServices");
        
        /* Filtramos los pagos con LambaJ */
        List<Caja> pagos = select(movimientosList,FilterCaja.filterCajaByTipoMovimiento(MovimientoTipoServices.PAGOS_ID));
        Map<String,Double> clienteTotalPayment = FilterCaja.getPagosByCliente(pagos);
       
        for(Map.Entry<String,Double> entry : clienteTotalPayment.entrySet()){
            
            Cliente cliente =  clienteServices.get( Integer.parseInt( entry.getKey() ) );
            Liquidacion liquidacion     = liquidacionServices.getLastLiquidacionByCliente(cliente);
            ClienteSaldo clienteSaldo   = clienteSaldoServices.getSaldoActualByCliente(cliente);
            
            double totalPayment = entry.getValue();
            
            /* Se aplica el pago a la última liquidación del Cliente */
            if(liquidacion != null){
                if("N".equals( liquidacion.getPosponer_pago() ) && liquidacion.getImportePagado() == 0){
                    liquidacion.setImportePagado(totalPayment);
                    //double saldoAnterior = clienteSaldo.getSaldoAnterior();
                    clienteSaldo.setSaldoAnterior(clienteSaldo.getSaldoActual());
                    clienteSaldo.setSaldoActual(totalPayment - clienteSaldo.getSaldoActual());
                    
                    /*Actualizamos el pago de la Liquidación*/
                    liquidacionServices.update(liquidacion);
                    /*Registramos un nuevo mov para el saldo del Cliente */
                    clienteSaldoServices.insert(clienteSaldo);
                }
            }
           
            
        }
        
        /* A cada movimiento de la caja le asignamos el cierre */
        
        for(Caja movimiento : movimientosList){
           movimiento.setCierreCajaId(cierre);
           cajaDao.update(movimiento);
        }
        
    }

    @Override
    public double getTotalRetiros() {
        return totalRetiros;
    }

    @Override
    public double getTotalPagos() {
        return totalPagos;
    }

    @Override
    public double getTotalGastosDiarios() {
        return totalGastosDiarios;
    }

    @Override
    public double getTotalGastosBancos() {
        return totalGastosBancos;
    }
    
    
    
}
